﻿/// <reference path="_namespace.js" />

/*****************************************************************************
Ajax library class definition. Kevin Robinson 2008.
Class: ajax.xna.RayCasterPlayer
/*****************************************************************************/

$addNamespace("ajax.xna");
$imports("ajax.math.Vector3");
$imports("ajax.xna.RayCaster");

//-----------------------------------------------------------------------------
ajax.xna.RayCasterPlayer = function(rayCaster)
{
    rayCaster = ajax.xna.RayCaster.cast(rayCaster);
    ajax.xna.RayCasterPlayer.superConstructor.call(this, rayCaster.getDocument());
    this._initialize(rayCaster);                
}
ajax.lang.extend("ajax.xna.RayCasterPlayer", "ajax.components.Component");
if ($getDesignMode())
    ajax.xna.RayCasterPlayer.prototype = ajax.components.Component.prototype;
//-----------------------------------------------------------------------------

    
// Public members
//-----------------------------------------------------------------------------
ajax.xna.RayCasterPlayer.prototype.rayCaster    = null;
ajax.xna.RayCasterPlayer.prototype.position     = ajax.math.Vector3.prototype;
ajax.xna.RayCasterPlayer.prototype.direction    = ajax.math.Vector3.prototype;
ajax.xna.RayCasterPlayer.prototype.plane        = ajax.math.Vector3.prototype;

// public methods
//-----------------------------------------------------------------------------

ajax.xna.RayCasterPlayer.prototype._initialize = function(rayCaster)
{        
    this.rayCaster  = rayCaster;
    this.position   = new ajax.math.Vector3();
    this.direction  = new ajax.math.Vector3(-1, 0, 0);
    this.plane      = new ajax.math.Vector3(0, 0.66, 0);
    // Start listening for key presses from the rayCaster.
    this.getKeyboard().setListenForKeys(this.getWindow(), this.getDocument(), true);
}

//-----------------------------------------------------------------------------
ajax.xna.RayCasterPlayer.prototype.update = function(gameTime)
{
    gameTime        = ajax.drawing.Timer.cast(gameTime);
    
    // Here we define standard keyboard (or mouse) control.
    var moveSpeed   = gameTime.elapsedTime * 0.002;
    var rotSpeed    = gameTime.elapsedTime * 0.002;
    
    var allKeys     = this.getKeyboard().getKeys();
    var keyState    = this.getKeyboard().getCurrentKeyboardState();    
    
    this.rayCaster  = ajax.xna.RayCaster.cast(this.rayCaster);
    
    // Movement        
    if (keyState[allKeys.KeyUp] || keyState[allKeys.KeyDown])
    {           
        var moveSpeed   = gameTime.elapsedTime * 0.002;
        var actualSpeed = keyState[allKeys.KeyUp] ? moveSpeed : -moveSpeed;
        // Calc new position
        var moveBy = ajax.math.Vector3.multiplyScalar(this.direction, actualSpeed);
        
        var newPos = ajax.math.Vector3.add(this.position, moveBy);        
        
        // Sepatate the X & Y checks to enable sliding collision.        
        if (this.rayCaster.worldMap.blocks[parseInt(newPos.x)][parseInt(this.position.y)] == 0)
            this.position.x = newPos.x;
        if (this.rayCaster.worldMap.blocks[parseInt(this.position.x)][parseInt(newPos.y)] == 0)
            this.position.y = newPos.y;                     
    }    
    
    // Strafe
    if (keyState[allKeys.KeyA] || keyState[allKeys.KeyS])
    {
        var moveSpeed = gameTime.elapsedTime * 0.002;
        var actualSpeed = keyState[allKeys.KeyS] ? moveSpeed : -moveSpeed;
        // Calc the position from normalized plane
        var moveBy = ajax.math.Vector3.multiplyScalar(ajax.math.Vector3.normalize(this.plane), actualSpeed);
        var newPos = ajax.math.Vector3.add(this.position, moveBy);
                            
        // Seperate the X & Y checks to enable sliding collision
        if (this.rayCaster.worldMap.blocks[parseInt(newPos.x)][parseInt(this.position.y)] == 0)
            this.position.x = newPos.x;
        if (this.rayCaster.worldMap.blocks[parseInt(this.position.x)][parseInt(newPos.y)] == 0)
            this.position.y = newPos.y;
    }
    
    // Rotation
    if (keyState[allKeys.KeyLeft] || keyState[allKeys.KeyRight])
    {
        var rotSpeed        = gameTime.elapsedTime * 0.002;
        var actualRotSpeed  = keyState[allKeys.KeyLeft] ? rotSpeed : -rotSpeed;
        
        var mat = ajax.math.Matrix.rotateZ(actualRotSpeed);
        
        // both camera direction and camera plane must be rotated
        this.direction = mat.transformVertex(this.direction);
        this.plane     = mat.transformVertex(this.plane);                        
    }       
}

// Statics
//-----------------------------------------------------------------------------
ajax.xna.RayCasterPlayer.cast = function(obj)
{///<returns type="ajax.xna.RayCasterPlayer"/>
    return obj;
}